using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO.Ports;
using System.Threading;
using System.Threading.Tasks;
using AvaloniaApplication1.IServices;
using AvaloniaApplication1.Models.DTOModel;
using AvaloniaApplication1.Service;
using AvaloniaApplication1.ViewModels.ModbusCardViewModel;
using AvaloniaApplication1.Views.ModbusCardView;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Modbus.Device;
using Modbus.IO;
using SukiUI.Dialogs;

namespace AvaloniaApplication1.Models
{
    // 连接类型标识
    public enum ModbusConnectionType
    {
        RtuOverTcp,
        Rtu
    }


    // TCP 配置（适用于 RtU over TCP 或仅 TCP 的情况）
    public class ModbusTcpConfig
    {
        public string TcpName { get; set; } = string.Empty; // 然后把port可以设置为字典存储<TcpName,int> 暂时不实现
        public string Server { get; set; } = string.Empty;

        public Dictionary<string, int> Ports { get; set; } = new();
        public int Timeout { get; set; } // 读取超时，单位可自定义
    }

    // 串口配置（仅串口使用）
    public class ModbusSerialConfig
    {
        public string SerialName { get; set; } = string.Empty;
        public int BaudRate { get; set; } = 9600;
        public int DataBits { get; set; } = 8;
        public StopBits StopBits { get; set; } = StopBits.One;

        /// <summary>
        /// 奇偶校验
        /// </summary>
        public Parity Paritys { get; set; } = Parity.None; // 默认无

        /// <summary>
        /// 读取超时，单位毫秒
        /// </summary>
        public int ReadTimeout { get; set; } = 3000;

        /// <summary>
        /// 写入超时，单位毫秒
        /// </summary>
        public int WriteTimeout { get; set; } = 3000;
    }

    /// <summary>
    /// 单个从站信息
    /// </summary>
    public partial class SlaveInfo : ObservableObject
    {
        /// <summary>
        /// 从站 ID
        /// </summary> 
        [ObservableProperty] private byte _slaveId = 1;

        /// <summary>
        /// 起始地址
        /// </summary>
        [ObservableProperty] private ushort _startAddress = 0;

        /// <summary>
        /// 读取数量
        /// </summary>
        [ObservableProperty] private ushort _readRegisterCount = 30;

        [ObservableProperty] private int _intervalTime = 2000;
        // 寄存器数据点
        [ObservableProperty] private ObservableCollection<RegisterDataPoints> _dataPoints = new();

        /// <summary>
        /// 初始化指定数量的数据点
        /// </summary>
        /// <param name="count">数据点数量</param>
        public void InitializeDataPoints(int count)
        {
            if (count < 0 || count > ushort.MaxValue)
                throw new ArgumentOutOfRangeException(nameof(count), "数据点数量必须在0到65535之间");
            DataPoints.Clear();
            for (ushort i = 0; i < count; i++)
            {
                DataPoints.Add(new RegisterDataPoints
                {
                    Address = (ushort)(StartAddress + i),
                });
            }
        }

        /// <summary>
        /// 根据起始地址和读取数量自动初始化
        /// </summary>
        public void AutoInitializeDataPoints()
        {
            InitializeDataPoints(ReadRegisterCount);
        }
    }
    // 统一的 Modbus 配置（聚合）
    public partial class ModbusConfig : ObservableObject
    {
        /// <summary>
        /// 设备名称
        /// </summary>
        [ObservableProperty] private string? _deviceName = string.Empty;

        /// <summary>
        /// 创建时间
        /// </summary>
        [ObservableProperty] private DateTime _createdTime;

        /// <summary>
        /// 连接类型
        /// </summary>
        [ObservableProperty] private ModbusConnectionType _connectionType;

        /// <summary>
        /// 从站配置
        /// </summary>
        [ObservableProperty] private SlaveInfo _slaveInfo = new SlaveInfo();

        /// <summary>
        /// 主站配置
        /// </summary>
        [ObservableProperty] private ModbusMaster? _master;

        /// <summary>
        /// 连接状态
        /// </summary>
        [ObservableProperty] private bool _isConnected = false;

        // /// <summary>
        // /// 轮询间隔时间
        // /// </summary>
        // [ObservableProperty] private int _intervalTime = 2000;

        /// <summary>
        /// Modbus管理器
        /// </summary>
        [ObservableProperty] private IModbusManager _modbusManager;

        // 具体配置按类型存储在对应属性中
        [ObservableProperty] private ModbusTcpConfig _tcpConfig = new ModbusTcpConfig();
        [ObservableProperty] private ModbusSerialConfig _serialConfig = new ModbusSerialConfig();
        /// <summary>
        /// 轮询任务取消源
        /// </summary>
        private CancellationTokenSource _cancellationTokenSource;
        /// <summary>
        /// 连接命令
        /// </summary>
        public IRelayCommand ConnectDeviceCommand { get; }

        /// <summary>
        /// 断开连接命令
        /// </summary>
        public IRelayCommand DisconnectDeviceCommand { get; }

        /// <summary>
        /// 配置命令
        /// </summary>
        public IRelayCommand SlaveConfigureDeviceCommand { get; }

        /// <summary>
        /// 移除设备命令
        /// </summary>
        public IRelayCommand RemoveModbusDeviceCommand { get; }

        /// <summary>
        /// 设备配置
        /// </summary>
        public IRelayCommand DeviceConfigCommand { get; }

        private ISukiDialogManager DialogManager { get; set; }

        // 构造函数示例，便于创建时初始化必填字段
        public ModbusConfig(string deviceName, DateTime createdTime, ModbusConnectionType connectionType,
            SlaveInfo slaveInfo, ModbusMaster? master,
            bool isConnected, IModbusManager modbusManager, ISukiDialogManager dialogManager)
        {
            DialogManager = dialogManager;
            ModbusManager = modbusManager;
            DeviceName = deviceName;
            CreatedTime = createdTime;
            ConnectionType = connectionType;
            SlaveInfo = slaveInfo;
            Master = null;
            IsConnected = isConnected;
            // IntervalTime = intervalTime;
            ConnectDeviceCommand = new RelayCommand(() => ConnectDevice());
            DisconnectDeviceCommand = new RelayCommand(() => DisconnectDevice());
            SlaveConfigureDeviceCommand = new RelayCommand(() => SlaveConfigureDevice());
            DeviceConfigCommand = new RelayCommand(() => DeviceConfigureDevice());
            RemoveModbusDeviceCommand = new RelayCommand(RemoveDevice);
            _cancellationTokenSource = new CancellationTokenSource();
        }


        // 无参构造函数 - 用于 DI 容器序列化/反序列化
        public ModbusConfig()
        {
            SlaveInfo = new SlaveInfo();
            TcpConfig = new ModbusTcpConfig();
            SerialConfig = new ModbusSerialConfig();
            Master = null;
            _cancellationTokenSource = new CancellationTokenSource();
            // 命令将在属性注入后初始化
            ConnectDeviceCommand = new RelayCommand(() => ConnectDevice());
            DisconnectDeviceCommand = new RelayCommand(() => DisconnectDevice());
            SlaveConfigureDeviceCommand = new RelayCommand(() => SlaveConfigureDevice());
            RemoveModbusDeviceCommand = new RelayCommand(RemoveDevice);
        }

        private async void ConnectDevice()
        {
            // 实现连接逻辑
            if (!string.IsNullOrEmpty(DeviceName))
            {
                // 重新初始化 CancellationTokenSource
                if (_cancellationTokenSource.IsCancellationRequested)
                {
                    _cancellationTokenSource = new CancellationTokenSource();
                }
                var reslut = await ModbusManager.ConnectModbusDeviceAsync(DeviceName, TcpConfig.TcpName);
                if (reslut)
                {
                    DialogManager.CreateDialog().WithContent("连接成功").WithActionButton("关闭", _ => { }, true)
                        .TryShow();
                }

                if (IsConnected)
                {
                    // 更新从站信息
                    SlaveInfo.AutoInitializeDataPoints();
                   StartPolling(SlaveInfo.IntervalTime,_cancellationTokenSource.Token);
                }
            }
        }
        public async void StartPolling(int intervalTime,CancellationToken cancellationToken)
        {
            try
            {
                while (!cancellationToken.IsCancellationRequested)
                {
                    await Task.Delay(intervalTime, cancellationToken);
                    await ModbusManager.ReadHoldingRegistersAsync(DeviceName);
                }
            }
            catch (OperationCanceledException)
            {
                // 正常取消，无需处理
            }
        }
        private async void DisconnectDevice()
        {
            // 实现断开连接逻辑
            if (!string.IsNullOrEmpty(DeviceName))
            {
                // 取消之前的轮询任务
                _cancellationTokenSource?.Cancel();
                var reslut = await ModbusManager.DisconnectModbusDeviceAsync(DeviceName);
                if (reslut)
                {
                    DialogManager.CreateDialog().WithContent("断开成功").WithActionButton("关闭", _ => { }, true)
                        .TryShow();
                }
            }
        }

        private void SlaveConfigureDevice()
        {
            // 实现从站配置
            if (string.IsNullOrEmpty(DeviceName)) return;
            var slaveViewmodel = new SlaveViewModel(DeviceName, ModbusManager);
            var slaveView = new SlaveView
            {
                DataContext = slaveViewmodel
            };
            DialogManager.CreateDialog().WithContent(slaveView)
                .WithActionButton("取消", _ => { DialogManager.DismissDialog(); }).TryShow();
        }

        private void RemoveDevice()
        {
            // 实现移除设备逻辑
            if (!string.IsNullOrEmpty(DeviceName))
            {
                // 取消之前的轮询任务
                _cancellationTokenSource?.Cancel();
                ModbusManager.RemoveModbusDeviceAsync(DeviceName);
            }
        }

        private void DeviceConfigureDevice()
        {
            if (!string.IsNullOrEmpty(DeviceName))
            {
                var deviceConfigViewmodel = new ModbusTcpConfigViewModel(DeviceName, ModbusManager);
                var deviceConfigView = new ModbusTcpConfigView
                {
                    DataContext = deviceConfigViewmodel
                };
                DialogManager.CreateDialog().WithContent(deviceConfigView)
                    .WithActionButton("取消", _ => { DialogManager.DismissDialog(); }).TryShow();
            }
        }
    }
}